from Tkinter import *
import tkFileDialog 
from shpReader import *
from CoordTransform import *
from VectorComputation import *
from GeometryComputation import *
from Histogram import *
import time
from BVAnalysis import *

class MAGUI():
    def __init__(self,root):
        self.root = root 
        self.selectVectID=[]
        self.selectedVec=[]
        
    def openMoveVecDialogue(self):
        mvName=tkFileDialog.askopenfilename(filetypes=[('File of Type:', '*.shp')], title='Open Movement Vector')  
        print mvName
        initialAll=self.coord_transformer.transformMVCoords(mvName)
        self.mvCoords=initialAll[0]
        self.mvDbfDict=initialAll[1]
        self.mvFieNa=initialAll[2]
        self.mvInitialCoords={}
        self.mvOriginCoords={}
        self.mvDestinCoords={}
        self.mvTransOriginCoords={}
        self.mvTransDestinCoords={}
        
        for k, c in self.mvCoords.items():
            self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='black',tags='moveVec')
            self.cav_map.create_oval((c[1][0]-2, c[1][1]-2, c[1][0]+2, c[1][1]+2), fill='red', tags=('originPoints'))
            self.cav_map.create_oval((c[1][2]-2, c[1][3]-2, c[1][2]+2, c[1][3]+2), fill='green', tags=('destinPoints'))
            self.mvInitialCoords[k]=c[0]
            self.mvOriginCoords[k]=(c[0][0],c[0][1])
            self.mvDestinCoords[k]=(c[0][2],c[0][3])
            self.mvTransOriginCoords[k]=(c[1][0], c[1][1])
            self.mvTransDestinCoords[k]=(c[1][2], c[1][3])
            
        self.vc=VectorComputation(self.mvInitialCoords)
        self.vc.computeDirection()
        self.vc.computeDistance()
        
        self.cav_map.pack(expand=1)
        
    def openSenFaciDialogue(self):
        sfName=tkFileDialog.askopenfilename(filetypes=[('File of Type:', '*.shp')], title='Open Sensitive Facility')  
        print sfName
        self.sfCoords = self.coord_transformer.transformMVCoords(sfName)[0]           
        self.sfInitialCoords={}
        self.sfTransCoords={}
        for k, c in self.sfCoords.items():
            self.cav_map.create_polygon(tuple(c[1]),fill='blue',outline='blue',tags='sfShp')
            self.sfInitialCoords[k]=c[0]
            self.sfTransCoords[k]=c[1]
        
            
    def openBaseShpDialogue(self):
        bsName=tkFileDialog.askopenfilename(filetypes=[('File of Type:', '*.shp')], title='Open Base Shapefile')
        print bsName
        if bsName:
            self.drawMap(bsName)
            self.createShortcutMenu()   
            self.shpTL.bind('<Button-3>', self.popupShortcutMenu)
    
    def drawMap(self,shpName):
        self.shpTL = Toplevel()
        self.shpTL.title('Map')
        self.shpTL.config(height=700, width=1000)
        
        self.cav_map = Canvas(self.shpTL,bg='white')
        self.cav_map.config(height = 650, width=950)
        
        self.coord_transformer=CoordTransformation(shpName)
        
        self.sceneCoords = self.coord_transformer.transformBSCoords()
        for c in self.sceneCoords.values():
            self.cav_map.create_polygon(tuple(c),fill='grey',outline='white',tags='baseShp')
        self.cav_map.pack(expand=1)
            
    def createRootMenu(self):
        menubar=Menu(self.root)
        
        openMenu=Menu(menubar, tearoff=0)
        openMenu.add_command(label='Base Shapefile', command=self.openBaseShpDialogue)
        openMenu.add_command(label='Movement Vector', command=self.openMoveVecDialogue) 
        openMenu.add_command(label='Sensitive Facilities', command=self.openSenFaciDialogue)         
            
        esdaMenu=Menu(menubar, tearoff=0)
        esdaMenu.add_command(label="Histogram")
        esdaMenu.add_command(label="Moran's I")
            
        menubar.add_cascade(label='Open', menu=openMenu)
        menubar.add_cascade(label='ESDA', menu=esdaMenu)
        
        self.root['menu']=menubar
        
    def createShortcutMenu(self):
        menubar=Menu(self.shpTL)        
        
        menubar.add_command(label='Select Vectors by Attributes', command=self.selectByAttr)
        menubar.add_command(label='Select Vectors by Rectangle', command=self.selectByRect)
        menubar.add_command(label='Clear Selections', command=self.clearSelect)
        menubar.add_command(label='Distance Histogram', command=self.produceDistHistDial)
        menubar.add_command(label='Direction Histogram', command=self.drawDirectHistogram)
        menubar.add_command(label="Create SRZ", command=self.createSRZ)
        menubar.add_command(label="Bivariate Analysis", command=self.doBivarAnalysis)
        
        self.shortcutMenu=menubar
        
    def popupShortcutMenu(self, event):
        self.shortcutMenu.post(event.x, event.y)
        
    def selectByAttr(self):
        self.selectTL = Toplevel()
        self.selectTL.title('Select Vectors by Attributes')
        self.selectTL.config(height=500, width=300)
        
        Label(self.selectTL, text='Directions:').grid(row=2, column=1)
        Label(self.selectTL, text='Distances:').grid(row=4, column=1)
        
        self.omDirecVar=StringVar(self.selectTL)
        self.omDirecVar.set('East')
        omDirec=OptionMenu(self.selectTL, self.omDirecVar, 'East','NorthEast', 'North', 'NorthWest', 'West',
                           'SouthWest', 'South', 'SouthEast')
        omDirec.grid(row=2, column=3)
        
        self.omDistVar=StringVar(self.selectTL)
        self.omDistVar.set('>=')
        omDist=OptionMenu(self.selectTL, self.omDistVar,'>=','<=')
        omDist.grid(row=4, column=3)
        
        self.edVar=StringVar(self.selectTL)
        entryDist=Entry(self.selectTL, textvariable=self.edVar)
        self.edVar.set('')
        entryDist.grid(row=4, column=4)
        
        self.omDistUnitVar=StringVar(self.selectTL)
        self.omDistUnitVar.set('Feet')
        omDistUnit=OptionMenu(self.selectTL, self.omDistUnitVar,'Feet','Miles')
        omDistUnit.grid(row=4, column=5)
        
        okSelectButton=Button(self.selectTL, text='OK', command=self.okInSelectByAttr)
        okSelectButton.grid(row=6, column=3)
        cancelSelectButton=Button(self.selectTL, text='Cancel', command=self.closeSelectByAttrTL)
        cancelSelectButton.grid(row=6, column=5) 
        
    def closeSelectByAttrTL(self):
        self.cav_map.delete('selectedVec')
        self.selectTL.destroy()
        
    def okInSelectByAttr(self):
        self.cav_map.delete('selectedVec')
        self.selectedVec=[]
        if self.omDirecVar.get() and self.edVar.get():
            for k, v in self.vc.vectDirect.items(): 
                
                if v[1]==self.omDirecVar.get():
                    if self.omDistUnitVar.get()== 'Feet':
                        if self.omDistVar.get()=='>=':
                            if self.vc.vectDist[k][0] >= float(self.edVar.get()):
                                self.selectedVec.append(k)
                        elif self.omDistVar.get()=='<=':
                            if self.vc.vectDist[k][0] <= float(self.edVar.get()):
                                self.selectedVec.append(k)
                    elif self.omDistUnitVar.get()== 'Miles':
                        if self.omDistVar.get()=='>=':
                            if self.vc.vectDist[k][1] >= float(self.edVar.get()):
                                self.selectedVec.append(k)
                        elif self.omDistVar.get()=='<=':
                            if self.vc.vectDist[k][1] <= float(self.edVar.get()):
                                self.selectedVec.append(k)  
                                
            for sv in self.selectedVec:
                self.cav_map.create_line(tuple(self.mvCoords[sv][1]),arrow=LAST,fill='red',tags='selectedVec')
                
        if not self.edVar.get():
            for k, v in self.vc.vectDirect.items():
                if v[1]==self.omDirecVar.get():
                    self.selectedVec.append(k) 
                    
            for sv in self.selectedVec:
                self.cav_map.create_line(tuple(self.mvCoords[sv][1]),arrow=LAST,fill='red',tags='selectedVec')
                
    def selectByRect(self):
        self.cav_map.bind('<Button-1>', self.mouseLeftClick)
        self.cav_map.bind('<ButtonRelease-1>', self.mouseLeftRelease)
        self.cav_map.bind('<B1-Motion>', self.mouseMove)
        
    def mouseLeftClick(self,event):
        '''response function for mouse left click event on the cav_map:
        mainly to assign the event's coordinates to firstX and firstY 
        '''       
        self.cav_map.delete('selector')
        self.cav_map.delete('selectVect')
        self.firstX=event.x
        self.firstY=event.y
            
    def mouseLeftRelease(self,event):
        '''response function for mouse left release event on the mapCav:
        mainly to create the selected rectangle, save the selected polygons' ID in the selectedPolyID
        and highlight the selected polygons
        '''        
        # create the selected rectangle
        self.selectVectID=[]

        self.cav_map.delete('movingRectangle')
        self.lastX=event.x
        self.lastY=event.y
        self.cav_map.create_rectangle((self.firstX,self.firstY,self.lastX,self.lastY), outline='black',tags=('selector'))
        
        #save the selected polygons' ID in the selectVectID
        rect = [self.firstX,self.firstY,self.lastX,self.lastY]
        for k, c in self.mvCoords.items():
            if rectangleIntersectVector(rect,c[1]):
                self.selectVectID.append(k)
        
        #highlight the selected polygons
        for k, c in self.mvCoords.items():
            if k in self.selectVectID:
                self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='yellow',tags='selectVec')
        self.cav_map.tag_raise('selector')   
        
    def mouseMove(self,event):
        '''response function for mouse move event on the mapCav:
        mainly to move the selected rectangle
        '''
        self.cav_map.delete('movingRectangle')
        self.cav_map.create_rectangle((self.firstX,self.firstY,event.x,event.y), outline='black',tags=('movingRectangle'))
        
    def clearSelect(self):        
        self.cav_map.delete('movingRectangle')
        self.cav_map.delete('selector')
        self.cav_map.delete('selectedVec')
        self.cav_map.delete('selectVec')
        self.selectVectID=[]
        self.selectedVec=[]  
    
    def produceDistHistDial(self):
        self.distHistParaTL = Toplevel()
        self.distHistParaTL.title('Distance Histogram Parameter Input')
        self.distHistParaTL.config(height=500, width=300)
        
        Label(self.distHistParaTL, text='Starting Distance:').grid(row=2, column=1)        
        Label(self.distHistParaTL, text='Interval:').grid(row=4, column=1)
        Label(self.distHistParaTL, text='Number of Bins').grid(row=6, column=1)
        
        self.stDistVar=StringVar(self.distHistParaTL)
        entryStDist=Entry(self.distHistParaTL, textvariable=self.stDistVar)
        self.stDistVar.set('')
        entryStDist.grid(row=2, column=3)
        
        self.intervalVar=StringVar(self.distHistParaTL)
        entryInterval=Entry(self.distHistParaTL, textvariable=self.intervalVar)
        self.intervalVar.set('')
        entryInterval.grid(row=4, column=3)
        
        self.noOfBinVar=StringVar(self.distHistParaTL)
        entryNoOfBin=Entry(self.distHistParaTL, textvariable=self.noOfBinVar)
        self.noOfBinVar.set('')
        entryNoOfBin.grid(row=6, column=3)      
              
        okSelectButton=Button(self.distHistParaTL, text='OK', command=self.drawDistHistogram)
        okSelectButton.grid(row=8, column=3)
        cancelSelectButton=Button(self.distHistParaTL, text='Cancel', command=self.closeHistWindow)
        cancelSelectButton.grid(row=8, column=5)  
        
    def closeHistWindow(self):
        self.distHistParaTL.destroy()
        
    
    def drawDistHistogram(self):
        self.distHistTL= Toplevel()
        self.distHistTL.title('Distance Histogram')
        self.cav_hist=Canvas(self.distHistTL,bg='white')
        self.cav_hist.config(height=500, width=500)
        
        if len(self.selectedVec)==0 and len(self.selectVectID)==0:
            allSelectedVec=[]
            histPara=createDistHistoPara(self.vc.vectDist, self.stDistVar.get(), self.intervalVar.get(),self.noOfBinVar.get())
            distMomentList=computeDistMoments(self.vc.vectDist)
        else:
            allSelectedVec=[]
            allSelectedVecDist={}
            allSelectedVec.extend(self.selectedVec)
            allSelectedVec.extend(self.selectVectID)
            
            for vdk, vdv in self.vc.vectDist.items():
                if vdk in allSelectedVec:
                    allSelectedVecDist[vdk]=vdv
                    
            histPara=createDistHistoPara(allSelectedVecDist, self.stDistVar.get(), self.intervalVar.get(),self.noOfBinVar.get())
            distMomentList=computeDistMoments(allSelectedVecDist)
            
        maxNO=((max(histPara.values())/10)+1)*10
        
        self.cav_hist.create_line((25,400,400,400),arrow='last')
        self.cav_hist.create_line((25,400,25,25),arrow='last')
        
        hk=histPara.keys()
        hk.sort()
        
        if self.noOfBinVar.get()=='':
            histIntervalDist=30.0
        else:
            histIntervalDist=300/float(self.noOfBinVar.get())
            
        print histPara
        
        for i in range(len(hk)-1):
            histItemTag='distHistr%d' %(i,)
            self.cav_hist.create_rectangle((50+histIntervalDist*i, 400-((histPara[hk[i]]*350)/maxNO), 50+histIntervalDist*(i+1), 400),outline='black', tags=histItemTag)
            self.cav_hist.create_text((50+histIntervalDist*i+(histIntervalDist/2), 400-((histPara[hk[i]]*350)/maxNO)-10), text="%d" %(histPara[hk[i]],))
            if i%2==0:
                self.cav_hist.create_text((50+histIntervalDist*i,410),text="%.2f" %(hk[i],))
            else:
                self.cav_hist.create_text((50+histIntervalDist*i,420),text="%.2f" %(hk[i],))                
            def handler(event, self=self, histItemTag=histItemTag, leftDist=hk[i], rightDist=hk[i+1], selectionID=allSelectedVec):
                return self.histInteractVector(event, histItemTag, leftDist, rightDist, selectionID)
        
            self.cav_hist.tag_bind(histItemTag, '<Button-1>', handler)
            
        self.cav_hist.create_text((50+(len(hk)-1)*histIntervalDist,410),text="%.2f" %(hk[len(hk)-1],))
        
        for j in range(11):
            self.cav_hist.create_line((25,50+j*35,30,50+j*35),arrow='none')
            self.cav_hist.create_text(15, 50+j*35, text="%d" %(maxNO-(maxNO/10)*j))
            
        self.cav_hist.create_text((380,25),text="mean = %.2f" %(distMomentList[0],), font=("Times", "14", "bold"))
        self.cav_hist.create_text((380,40),text="variance = %.2f" %(distMomentList[1],), font=("Times", "14", "bold"))
        
        self.cav_hist.bind('<Button-3>', self.clearHistSelection)
            
        self.cav_hist.pack()
                    
        
    def histInteractVector(self,event,histItemTag, leftDist, rightDist, selectionID):
        distHistSelection=[]
        if not selectionID:
            self.cav_hist.itemconfig(histItemTag, fill='red')
            for key, value in self.vc.vectDist.items():
                if value[1]<=rightDist and value[1]>=leftDist:
                    distHistSelection.append(key)
                    
            for k, c in self.mvCoords.items():
                if k in distHistSelection:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='blue',tags='distHistSelectVec')
                    
        else:
            self.cav_hist.itemconfig(histItemTag, fill='red')
            for key, value in self.vc.vectDist.items():
                if key in selectionID:
                    if value[1]<=rightDist and value[1]>=leftDist:
                        distHistSelection.append(key)
                    
            for k, c in self.mvCoords.items():
                if k in distHistSelection:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='blue',tags='distHistSelectVec')            
    
        
    def clearHistSelection(self, event):
        if self.noOfBinVar.get()=='':
            nb=10
        else:
            nb=int(self.noOfBinVar.get())
        for i in range(nb):
            self.cav_hist.itemconfig('distHistr%d' %(i,), fill="")
        self.cav_map.delete('distHistSelectVec')
 
        
    def drawDirectHistogram(self):
        self.directHistTL= Toplevel()
        self.directHistTL.title('Direction Histogram')
        self.cav_direct_hist=Canvas(self.directHistTL,bg='white')
        self.cav_direct_hist.config(height=500, width=580)
        
        if len(self.selectedVec)==0 and len(self.selectVectID)==0:
            allSelectedVec=[]
            histPara=createDirectHistoPara(self.vc.vectDirect)
            directMomentList=computeDirectMoments(self.vc.vectDirect)
        else:
            allSelectedVec=[]
            allSelectedVecDirect={}
            allSelectedVec.extend(self.selectedVec)
            allSelectedVec.extend(self.selectVectID)
            
            for vdk, vdv in self.vc.vectDirect.items():
                if vdk in allSelectedVec:
                    allSelectedVecDirect[vdk]=vdv
                    
            histPara=createDirectHistoPara(allSelectedVecDirect)
            directMomentList=computeDirectMoments(allSelectedVecDirect)      
        
        maxNo= float(max(histPara.values()))  
        print histPara
        for k, v in histPara.items():
            directHistItemTag='directHistr%s' %(k,)

            self.cav_direct_hist.create_arc((250-(v*240)/maxNo,250-(v*240)/maxNo ,250+(v*240)/maxNo,250+(v*240)/maxNo),style = PIESLICE,start = k-30,extent = 30, width=2, tags=directHistItemTag)
            self.cav_direct_hist.create_text(250+((v*240)/maxNo-10)*ma.cos(deg2rad(k-15)), 250-((v*240)/maxNo-10)*ma.sin(deg2rad(k-15)), text="%d" %(v, ))
            def handler(event, self=self, directHistItemTag=directHistItemTag, rightDirect=k, selectionID=allSelectedVec):
                return self.directHistInteractVector(event, directHistItemTag, rightDirect, selectionID)
 
            self.cav_direct_hist.tag_bind(directHistItemTag, '<Button-1>', handler)
            
        self.cav_direct_hist.create_text((500,25),text="mean = %.2f" %(directMomentList[0],), font=("Times", "14", "bold"))
        self.cav_direct_hist.create_text((500,40),text="variance = %.2f" %(directMomentList[1],), font=("Times", "14", "bold")) 
        
        self.cav_direct_hist.bind('<Button-3>', self.clearDirectHistSelection)
        self.cav_direct_hist.pack()
    
    def directHistInteractVector(self, event, directHistItemTag, rightDirect, selectionID):
        directHistSelection=[]
        if not selectionID:
            self.cav_direct_hist.itemconfig(directHistItemTag, fill='red')
            for key, value in self.vc.vectDirect.items():

                if value[0]<= rightDirect and value[0]>=rightDirect-30:
                    directHistSelection.append(key)
                    
            for k, c in self.mvCoords.items():
                if k in directHistSelection:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='green',tags='directHistSelectVec')
                    
        else:
            self.cav_direct_hist.itemconfig(directHistItemTag, fill='red')
            for key, value in self.vc.vectDirect.items():
                if key in selectionID:
                    if value[0]<= rightDirect and value[0]>=rightDirect-30:
                        directHistSelection.append(key)
                    
            for k, c in self.mvCoords.items():
                if k in directHistSelection:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='green',tags='directHistSelectVec')        

        
    def clearDirectHistSelection(self, event):
        for i in range(12):
            self.cav_direct_hist.itemconfig('directHistr%s' %((i+1)*30,), fill="")
        self.cav_map.delete('directHistSelectVec')
        

    def createSRZ(self):
        self.srzTL = Toplevel()
        self.srzTL.title('SRZ Analysis')
        self.srzTL.config(height=500, width=300)
        
        Label(self.srzTL, text='Restriction Distance:').grid(row=2, column=1)        
        Label(self.srzTL, text='SRZ Analysis Result:').grid(row=4, column=1)
        
        self.srzDistVar=DoubleVar(self.srzTL)
        entrySRZDist=Entry(self.srzTL, textvariable=self.srzDistVar)
        entrySRZDist.grid(row=2, column=3)
        
        okButton=Button(self.srzTL, text='OK', command=self.produceSRZ)
        okButton.grid(row=2, column=5)
        self.srzResult=Text(self.srzTL)
        self.srzResult.grid(row=6, column=1)
        
    def produceSRZ(self):
        buList=[]
        t0=time.clock()
        for c in self.sfInitialCoords.values():
            bu=createBuffer(c, self.srzDistVar.get())   
            buList.append(bu)
            if bu.geom_type=='Polygon':                
                buTrans=self.coord_transformer.transformSFCoords(list(bu.exterior.coords))
                self.cav_map.create_polygon(tuple(buTrans), fill='', outline='yellow', tags='sfBuffer')       
        
        print time.clock()-t0
        
        srzToNonSRZ=0
        srzToSRZ=0
        nonSRZToSRZ=0
        nonSRZToNonSRZ=0
        
        t1=time.clock()
        
        for coord in self.mvInitialCoords.values():
            originInPoly=False
            destinInPoly=False
            for bul in buList:
                if not originInPoly:
                    originInPoly=(pointInPoly((coord[0],coord[1]), bul) or originInPoly)
                if not destinInPoly:
                    destinInPoly=(pointInPoly((coord[2],coord[3]), bul) or destinInPoly)
                
            if originInPoly and destinInPoly:
                srzToSRZ=srzToSRZ+1

            if originInPoly and (not destinInPoly):
                srzToNonSRZ=srzToNonSRZ+1

            if (not originInPoly) and destinInPoly:
                nonSRZToSRZ=nonSRZToSRZ+1

            if (not originInPoly) and (not destinInPoly):
                nonSRZToNonSRZ=nonSRZToNonSRZ+1

        print time.clock()-t1            
        noOfMove=len(self.mvCoords)    
        self.srzResult.insert(1.0, 'Type                      Counts   Ratio \n' )
        self.srzResult.insert(2.0, 'From SRZ to SRZ             %d       %f \n' %(srzToSRZ, srzToSRZ/float(noOfMove)))
        self.srzResult.insert(3.0, 'From SRZ to Non-SRZ         %d       %f \n' %(srzToNonSRZ, srzToNonSRZ/float(noOfMove)))
        self.srzResult.insert(4.0, 'From Non-SRZ to SRZ         %d       %f \n' %(nonSRZToSRZ, nonSRZToSRZ/float(noOfMove)))
        self.srzResult.insert(5.0, 'From Non-SRZ to Non-SRZ     %d       %f \n' %(nonSRZToNonSRZ, nonSRZToNonSRZ/float(noOfMove)))
        
    def doBivarAnalysis(self):
        self.baTL = Toplevel()
        self.baTL.title('Bivariate Analysis')
        self.baTL.config(height=500, width=300)
        
        Label(self.baTL, text='First Vairable:').grid(row=2, column=1)        
        Label(self.baTL, text='Number of Columns:').grid(row=4, column=1)
        Label(self.baTL, text='Second Varible:').grid(row=6, column=1)
        Label(self.baTL, text='Number of Rows:').grid(row=8, column=1)
        
        self.baFvVar=StringVar(self.baTL)
        self.baFvVar.set(self.mvFieNa[0])
        omBaFv=apply(OptionMenu,(self.baTL, self.baFvVar) + tuple(self.mvFieNa))
        omBaFv.grid(row=2, column=3)
        
        self.baNcVar=DoubleVar(self.baTL)
        entryBaNc=Entry(self.baTL, textvariable=self.baNcVar)
        entryBaNc.grid(row=4, column=3)
        
        self.baSvVar=StringVar(self.baTL)
        self.baSvVar.set(self.mvFieNa[0])
        omBaSv=apply(OptionMenu,(self.baTL, self.baSvVar) + tuple(self.mvFieNa))
        omBaSv.grid(row=6, column=3)
        
        self.baNrVar=DoubleVar(self.baTL)
        entryBaNr=Entry(self.baTL, textvariable=self.baNrVar)
        entryBaNr.grid(row=8, column=3)      
              
        okSelectButton=Button(self.baTL, text='OK', command=self.drawBAQuadrat)
        okSelectButton.grid(row=10, column=3)
        cancelSelectButton=Button(self.baTL, text='Cancel', command=self.cancelBaQuadrat)
        cancelSelectButton.grid(row=10, column=5)  
        
    def drawBAQuadrat(self):
        self.baQuadratTL= Toplevel()
        self.baQuadratTL.title('Bivariate Quadrat')
        self.cav_baQuadrat=Canvas(self.baQuadratTL,bg='white')
        self.cav_baQuadrat.config(height=500, width=500)
        
        if len(self.selectedVec)==0 and len(self.selectVectID)==0:
            allSelectedVec=[]
            bvMatrixResult=bvAnalysis(self.mvDbfDict, self.baFvVar.get(), self.baNcVar.get(),self.baSvVar.get(), self.baNrVar.get())
          
        else:
            allSelectedVec=[]
            allSelectedVecBVDict={}
            allSelectedVec.extend(self.selectedVec)
            allSelectedVec.extend(self.selectVectID)
            
            for vdk, vdv in self.mvDbfDict.items():
                if vdk in allSelectedVec:
                    allSelectedVecBVDict[vdk]=vdv
                    
            bvMatrixResult=bvAnalysis(allSelectedVecBVDict, self.baFvVar.get(), self.baNcVar.get(),self.baSvVar.get(), self.baNrVar.get())
            
        self.bvMatrix=bvMatrixResult[0]
        fvIntervals=bvMatrixResult[1]
        svIntervals=bvMatrixResult[2]
        
        self.cav_baQuadrat.create_line((50,450,450,450),arrow='last')
        self.cav_baQuadrat.create_text((475, 450), text=self.baFvVar.get())
        self.cav_baQuadrat.create_line((50,450,50,50),arrow='last')
        self.cav_baQuadrat.create_text((50, 25), text=self.baSvVar.get())    
            
        bvMatrixNo=[]
        for i in range(len(self.bvMatrix)):
            bvMatrixNo.append([])
            for j in range(len(self.bvMatrix[i])):
                bvMatrixNo[i].append(len(self.bvMatrix[i][j]))
        
        bvColInterval=350/float(self.baNcVar.get())
        bvRowInterval=350/float(self.baNrVar.get())
        
        for svi in range(len(svIntervals)):
            self.cav_baQuadrat.create_text((25, 75+bvRowInterval*svi),text="%.2f" %(svIntervals[len(svIntervals)-1-svi],))
            
        for fvi in range(len(fvIntervals)):
            if fvi%2==0:
                self.cav_baQuadrat.create_text((75+bvColInterval*fvi, 460),text="%.2f" %(fvIntervals[fvi],))
            else:
                self.cav_baQuadrat.create_text((75+bvColInterval*fvi, 470),text="%.2f" %(fvIntervals[fvi],))
        
        for i in range(len(bvMatrixNo)):
            for j in range(len(bvMatrixNo[i])):
                bvItemTag='bv%d_%d' %(i,j)
                self.cav_baQuadrat.create_rectangle((75+bvColInterval*j, 425-bvRowInterval*i, 75+bvColInterval*(j+1), 425-bvRowInterval*(i+1)),outline='black', tags=bvItemTag)
                self.cav_baQuadrat.create_text((75+(j+0.5)*bvColInterval, 425-(i+0.5)*bvRowInterval), text="%d" %(bvMatrixNo[i][j],))
               
                def handler(event, self=self, bvItemTag=bvItemTag, bvNRow=i, bvNCol=j, selectionID=allSelectedVec):
                    return self.bvInteractVector(event, bvItemTag, bvNRow, bvNCol, selectionID)
            
                self.cav_baQuadrat.tag_bind(bvItemTag, '<Button-1>', handler)          
      
       
        self.cav_baQuadrat.bind('<Button-3>', self.clearBVSelection)
            
        self.cav_baQuadrat.pack()  
        
    def bvInteractVector(self,event,bvItemTag, bvNRow, bvNCol, selectionID):
        if not selectionID:
            self.cav_baQuadrat.itemconfig(bvItemTag, fill='red')                   
            for k, c in self.mvCoords.items():
                if k in self.bvMatrix[bvNRow][bvNCol]:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='purple',tags='bvSelectVec')
                    
        else:
            self.cav_baQuadrat.itemconfig(bvItemTag, fill='red')                  
            for k, c in self.mvCoords.items():
                if k in selectionID and k in self.bvMatrix[bvNRow][bvNCol]:
                    self.cav_map.create_line(tuple(c[1]),arrow=LAST,fill='purple',tags='bvSelectVec')  
        
    def clearBVSelection(self, event):
        for i in range(int(self.baNrVar.get())):
            for j in range(int(self.baNcVar.get())):
                self.cav_baQuadrat.itemconfig('bv%d_%d' %(i,j), fill="")
        self.cav_map.delete('bvSelectVec')
        
    def cancelBaQuadrat(self):
        self.baTL.destroy()
        self.baQuadratTL.destroy()
        
    
if __name__=='__main__':
    root=Tk()
    root.title('Movement Analysis')
    root.config(height = 600, width=600)
    magui=MAGUI(root)
    magui.createRootMenu()     
    root.mainloop()
    